//
//  EncryptionAndDecryption.m
//  iOSInterview
//
//  Created by macbook on 2025/5/30.
//

#import <UIKit/UIKit.h>
#import "EncryptionAndDecryption.h"
#import <Adjust/Adjust.h>
#import <CommonCrypto/CommonCryptor.h>
#import <CommonCrypto/CommonDigest.h>
#import <GTMBase64/GTMBase64.h>

#define apiKey          @"Uh5EzhZoHtUpqSAB"
#define tokenKey        @"uxgfzPDMcK35Bwr2V8o0lYe6RKbYQxvt"
#define encryptName     @"SLGPRUTO"
#define headName        @"JOGGHXW"
#define alias           @"wuniversal"


@implementation EncryptionAndDecryption

static EncryptionAndDecryption *_sharedInstance = nil;

+ (instancetype)sharedInstance {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedInstance = [[super allocWithZone:NULL] init];
    });
    return _sharedInstance;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    return [EncryptionAndDecryption sharedInstance];
}

- (id)copyWithZone:(NSZone *)zone {
    return self;
}

- (id)mutableCopyWithZone:(NSZone *)zone {
    return self;
}

- (void)requestWithParameters:(NSDictionary *)parameters {
  //headers
  NSMutableDictionary *_headers = [NSMutableDictionary dictionary];
  _headers[@"packageName"] = alias; //替换alias
  NSMutableDictionary *tokenDic = [NSMutableDictionary dictionary];
  tokenDic[@"sourceChannel"] = Adjust.attribution.trackerName;
  tokenDic[@"packageName"] = [NSBundle mainBundle].infoDictionary[@"CFBundleIdentifier"];
  tokenDic[@"version"] = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
  tokenDic[@"adid"] = Adjust.adid;
  tokenDic[@"idfa"] = Adjust.idfa;
  tokenDic[@"idfv"] = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
  tokenDic[@"userId"] = @"用户userId";
  tokenDic[@"uuId"] = @"用户uuId";
  _headers[headName] = [self encryptAES:[self dictionaryToJson:tokenDic] secretKey:tokenKey iv:tokenKey];  //替换headName, tokenKey

  //parameters
  NSMutableDictionary *_parameters = [NSMutableDictionary dictionary];
  if (parameters) {
    _parameters[encryptName] = [self encryptAES:[self dictionaryToJson:parameters] secretKey:apiKey iv:apiKey]; //替换encryptName, apiKey
  }

  //response
//  NSString *responseStr = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
//  NSString *responseDecryptStr = [self decryptAES:responseStr secretKey:@"apiKey" iv:@"apiKey"]; //替换apiKey
}

- (NSString *)encryptAES:(NSString *)originalString secretKey:(NSString *)key iv:(NSString *)iv {
    NSData *encryptData = [originalString dataUsingEncoding:NSUTF8StringEncoding];
    char keyPtr[(key.length == 16 ? kCCKeySizeAES128 : kCCKeySizeAES256) + 1];
    bzero(keyPtr, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    // IV
    char ivPtr[(key.length == 16 ? kCCKeySizeAES128 : kCCKeySizeAES256) + 1];
    bzero(ivPtr, sizeof(ivPtr));
    [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];

    NSUInteger dataLength = [encryptData length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesEncrypted = 0;

    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, keyPtr, (key.length == 16 ? kCCKeySizeAES128 : kCCKeySizeAES256), ivPtr, [encryptData bytes], dataLength, buffer, bufferSize, &numBytesEncrypted);

    if (cryptStatus == kCCSuccess) {
        NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
        NSData *base64Data = [GTMBase64 encodeData:resultData];
        NSString *base64String = [[NSString alloc] initWithData:base64Data encoding:NSUTF8StringEncoding];
        return base64String;
    }
    free(buffer);
    return nil;
}

- (NSString *)decryptAES:(NSString *)encryptedString secretKey:(NSString *)key iv:(NSString *)iv {
    NSData *decryptData = [GTMBase64 decodeData:[encryptedString
                                                 dataUsingEncoding:NSUTF8StringEncoding]];

    if (decryptData) {
        char keyPtr[(key.length == 16 ? kCCKeySizeAES128 : kCCKeySizeAES256) + 1];
        bzero(keyPtr, sizeof(keyPtr));
        [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

        char ivPtr[(key.length == 16 ? kCCKeySizeAES128 : kCCKeySizeAES256) + 1];
        bzero(ivPtr, sizeof(ivPtr));
        [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];

        NSUInteger dataLength = [decryptData length];
        size_t bufferSize = dataLength + kCCBlockSizeAES128;
        void *buffer = malloc(bufferSize);
        size_t numBytesEncrypted = 0;

        CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                              kCCAlgorithmAES128,
                                              kCCOptionPKCS7Padding,
                                              keyPtr,
                                              (key.length == 16 ? kCCKeySizeAES128 : kCCKeySizeAES256),
                                              ivPtr,
                                              [decryptData bytes],
                                              dataLength,
                                              buffer,
                                              bufferSize,
                                              &numBytesEncrypted);

        if (cryptStatus == kCCSuccess) {
            NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
            NSString *resultString = [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding];
            return resultString;
        }
        free(buffer);
    }

    return encryptedString;
}

- (NSString *)dictionaryToJson:(NSDictionary *)dic {
    NSString *json;
    if (dic) {
        NSError *error;
        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:0 error:&error];
        if (!error) {
            json = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
        } else {
            NSLog(@"JSON parse error: %@", error);
        }
    }
    return json;
}

@end
